﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using XNAGraffiti.ParticleSystems;

namespace XNAGraffiti
{
    public class FireGraffiti : Graffiti
    {
        private ParticleSystem m_fireParticles;
        private ParticleSystem m_smokePlumeParticles;
        private ParticleSystem m_sparkParticles;
        private ParticleSystem m_blueFireParticles;
        private ParticleSystem m_largeSparkParticles;

        public FireGraffiti(Game game) :base(game)
        {
            m_smokePlumeParticles = new SmokePlumeParticleSystem(game, game.Content);
            m_fireParticles = new FireParticleSystem(game, game.Content);
            m_sparkParticles = new SparkParticleSystem(game, game.Content);
            m_blueFireParticles = new BlueFireParticleSystem(game, game.Content);
            m_largeSparkParticles = new LargeSparkParticleSystem(game, game.Content);

            m_sparkParticles.DrawOrder = 50;
            m_smokePlumeParticles.DrawOrder = 100;
            m_blueFireParticles.DrawOrder = 550;
            m_fireParticles.DrawOrder = 500;
            m_largeSparkParticles.DrawOrder = 560;

            game.Components.Add(m_fireParticles);
            game.Components.Add(m_smokePlumeParticles);
            game.Components.Add(m_sparkParticles);
            game.Components.Add(m_blueFireParticles);
            game.Components.Add(m_largeSparkParticles);
        }

        public override void DrawLine(Point? startPoint, Point? endPoint)
        {
            if (!startPoint.HasValue || !endPoint.HasValue)
                return;

            var points = GetLinePoints(startPoint.Value, endPoint.Value);

            for (int i = 0; i < points.Length; i++)
            {
                var linePoint = points[i];
                m_fireParticles.AddParticle(ScreenPointToVector3(linePoint), Vector3.Zero);
                m_blueFireParticles.AddParticle(ScreenPointToVector3(linePoint), Vector3.Zero);
            }

            var point = ScreenPointToVector3(endPoint.Value);

            for (int i = 0; i < 4; i++)
            {
                m_largeSparkParticles.AddParticle(point, Vector3.Zero);
            }

            for (int i = 0; i < 1; i++)
            {
                m_sparkParticles.AddParticle(ScreenPointToVector3(endPoint.Value), Vector3.Zero);
            }

            m_smokePlumeParticles.AddParticle(ScreenPointToVector3(endPoint.Value), Vector3.Zero);
        }

        public override void Draw(GameTime gameTime)
        {
            // Compute camera matrices.
            float aspectRatio = (float)Game.GraphicsDevice.Viewport.Width /
                                (float)Game.GraphicsDevice.Viewport.Height;

            Matrix view = Matrix.CreateTranslation(0, -25, 0) *
                          Matrix.CreateRotationY(MathHelper.ToRadians(CameraRotation)) *
                          Matrix.CreateRotationX(MathHelper.ToRadians(CameraArc)) *
                          Matrix.CreateLookAt(new Vector3(0, 0, -CameraDistance),
                                              new Vector3(0, 0, 0), Vector3.Up);

            Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
                                                                    aspectRatio,
                                                                    1, 10000);

            m_fireParticles.SetCamera(view, projection);
            m_smokePlumeParticles.SetCamera(view, projection);
            m_sparkParticles.SetCamera(view, projection);
            m_blueFireParticles.SetCamera(view, projection);
            m_largeSparkParticles.SetCamera(view, projection);
        }
    }
}
